STL Iterator

Iterator
C++에서 복잡한 데이터 구조를 다루는 경우, 데이터 순회(traversal)를 위해 반복자(iterator)를 가장 흔하게
사용한다.

반복자는 컬렉션에서 항목 하나에 접근하는 방법과
그 항목의 다음 항목으로 이동하는 방법을 알고 있는 구조를 말한다.
따라서 반복자는 operator++와 operator!=를 구현해 주어야 한다.
STL Iterator
vector<string> names{"john", "jane", "jill", "jack"};
    begin()
컬렉션에서 첫번째 iterator를 반환받는다.

begin() 함수는 vector의 멤버 함수로도 정의되어 있고, 전역 함수로도 정의되어 있다.
(전역 함수는 멤버함수를 제공하지 않는 C 스타일의 저수준 배열을 사용할 때 좋다)
vector<string>::iterator it=names.begin(); // same begin(names)
반복자는 포인터처럼 *를 통해 반복자를 역참조해서 이름의 값을 출력할 수 있다.
접근하는 항목의 값을 변경할 수도 있다.
cout<<"first name is "<<*it<<'\n';
it->append(" goodall"s); // string.h append
cout<<"full name is "<<*it<<'\n';
operator++를 통해서 iterator가 다음 항목을 가르키도록 이동시킬 수 있다.
    end()
end()는 마지막 항목을 가르키는 것이 아닌, 마지막 항목 다음 위치를 가리킨다.
while(++it!=names.end()){
cout<<"another name: "<<*it<<'\n';
}
    rbegin() & rend()
begin(), end()의 역방향 순회를 위해 사용한다.
rbegin()은 마지막 항목을 가리키며, rend()는 첫 항목 바로 앞을 가르킨다.

rbegin, rend를 통해서 얻은 반복자는 operator++에 대해서 앞으로 한칸 이동함
for(auto ri=rbegin(names); ri!=rend(names); ++ri){
cout<<*ri;
if(ri+1!=rend(names)) cout<<", ";
}
cout<<endl;
반복자에 대해서 operator++ 외에 operator+와 같은 산술 연산도 가능하다.
    cbegin()/cend() & crbegin()/crend()
객체에 대한 변경을 허용하지 않는 const 반복자
vector<string>::const_reverse_iterator jack=crbegin(names);
// *jack+="reacher"; // error; const
모던 C++에서 범위 기반 for 루프를 통해 begin()에서 end() 직전까지 순회 가능하다.
범위 기반 for 루프를 사용할 때, *를 이용해서 역참조할 필요 없이 반복자를 이용해서 역참조 가능하다.

테스트 결과 operator++는 사용할 수 없음
for(auto& name: names) cout<<"name= "<<name<<'\n';
for(auto name: names)
// X
for(const auto& name: names)
// X const iterator